package utils

import (
	"encoding/json"
	"encoding/xml"
	"errors"
	"fmt"
	"kugo/log"
	"math/rand"
	"os"
	"reflect"
	"strconv"
	"time"
)

var r *rand.Rand

func GetTimeSecond() time.Time {
	return time.Now().Truncate(time.Second)
}

func TimeToInt(time time.Time) int64 {
	timestamp := time.Unix()
	return timestamp
}
func InitRand() {
	r = rand.New(rand.NewSource(time.Now().UnixNano()))
}

// 获取随机六位数
func GetRandSixInt() int {
	randomNumber := r.Intn(900000) + 100000
	return randomNumber
}

// 获取随机数 INT64
func GetRandInt64() int64 {
	randomNumber := r.Int63n(900000000)
	return randomNumber
}

// 获取随机数 INT
func GetRandInt() int {
	randomNumber := r.Intn(900000000)
	return randomNumber
}

func IsUndefined(str string) bool {
	return str == "undefined"
}

// 三目运算
func TernaryOperation(check bool, ret1 interface{}, ret2 interface{}) interface{} {
	if check {
		return ret1
	} else {
		return ret2
	}
}

// 过滤 空串和0 数据
func FilterNullData(data interface{}) []struct {
	Key   string
	Value string
} {
	var realData []struct {
		Key   string
		Value string
	}
	v := reflect.ValueOf(data)
	t := v.Type()
	for i := 0; i < v.NumField(); i++ {
		field := v.Field(i)
		fieldName := t.Field(i).Name
		fieldValue := field.Interface()
		strValue := ""
		if reflect.TypeOf(fieldValue).Kind() == reflect.String {
			strValue = fieldValue.(string)
			if strValue != "" {
				newKey := struct {
					Key   string
					Value string
				}{
					Key:   fieldName,
					Value: fmt.Sprintf(`"%s"`, strValue),
				}
				realData = append(realData, newKey)
			}
		} else if reflect.TypeOf(fieldValue).Kind() == reflect.Int8 {
			strValue = strconv.Itoa(int(fieldValue.(int8)))
			if strValue != "0" {
				newKey := struct {
					Key   string
					Value string
				}{
					Key:   fieldName,
					Value: strValue,
				}
				realData = append(realData, newKey)
			}
		} else {
			strValue = strconv.Itoa(fieldValue.(int))
			if strValue != "0" {
				newKey := struct {
					Key   string
					Value string
				}{
					Key:   fieldName,
					Value: strValue,
				}
				realData = append(realData, newKey)
			}
		}
	}
	return realData
}

// 未知结构体返回json串
func Struct2JSON(data interface{}) string {
	v := reflect.ValueOf(data)

	if v.Kind() == reflect.String {
		return data.(string)
	} else if v.Kind() != reflect.Pointer {
		return ""
	}

	jsonData, err := json.Marshal(data)
	if err != nil {
		panic(err)
	}

	return string(jsonData)
}

func PrintType(data interface{}) {
	dataType := reflect.TypeOf(data)
	log.Debug(fmt.Sprintln("Data Type:", dataType))
}

func ArrInterfaceToArrString(arr interface{}) []string {
	data, ok := arr.([]interface{})
	if !ok {
		return nil
	}
	var members []string
	for _, member := range data {
		if memberBytes, ok := member.([]byte); ok {
			members = append(members, string(memberBytes))
		} else {
			log.ErrLog("Failed to convert member to []byte")
			return nil
		}
	}
	return members
}

func ValueToString(data interface{}) (string, error) {
	value := reflect.ValueOf(data)
	valueType := value.Type()
	var result string
	switch valueType.Kind() {
	case reflect.Struct:
		ret, err := json.Marshal(data)
		if err != nil {
			return "", err
		} else {
			result = string(ret)
		}
	case reflect.String:
		return data.(string), nil
	case reflect.Int:
		return strconv.Itoa(data.(int)), nil
	case reflect.Int8:
		return strconv.Itoa(int(data.(int8))), nil
	case reflect.Int32:
		return strconv.Itoa(int(data.(int32))), nil
	case reflect.Int64:
		return strconv.FormatInt(data.(int64), 10), nil
	default:
		return "", errors.New("不知名的类型")
	}
	return result, nil

}

func StringToStruct(data interface{}, result interface{}) error {
	err := json.Unmarshal([]byte(data.(string)), result)
	if err != nil {
		typeName := reflect.TypeOf(result).String()
		log.ErrLog("数据类型转换出错:%s,%s", data.(string), typeName)
		return err
	}
	return nil
}

func GetStructName(model interface{}) string {
	return reflect.Indirect(reflect.ValueOf(model)).Type().Name()
}

func Int64ToString(num int64) string {
	return strconv.FormatInt(num, 10)
}

func StringToInt64(str string) int64 {
	num, err := strconv.ParseInt(str, 10, 64)
	if err != nil {
		fmt.Println("Error converting to int64:", err)
		return 0
	}
	return num
}

func StructToMap(obj interface{}) map[string]interface{} {
	objValue := reflect.ValueOf(obj)
	if objValue.Kind() == reflect.Ptr {
		objValue = objValue.Elem()
	}

	if objValue.Kind() != reflect.Struct {
		panic("Input obj must be a struct")
	}

	result := make(map[string]interface{})

	for i := 0; i < objValue.NumField(); i++ {
		field := objValue.Type().Field(i)
		value := objValue.Field(i).Interface()
		result[field.Name] = value
	}

	return result
}

func ReadConfig(filename string, model interface{}) error {
	// 读取配置文件
	data, err := os.ReadFile(filename)
	if err != nil {
		return err
	}

	// 解析配置文件
	err = xml.Unmarshal(data, model)
	if err != nil {
		return err
	}
	return nil
}
